// 由一个组件，向上找到最近的指定组件
function findComponentUpward(context, componentName){
    let parent = context.$parent;
    let name = parent.$options.name;
    
    while(parent && (!name || [componentName].indexOf(name) < 0)){
        parent = parent.$parent
        if(parent) name = parent.$options.name;
    }
    return parent;
}

// 向上找到所有的指定组件
function findComponentsUpward(context, componentName){
    let parents = [];
    const parent = context.$parent;
    if(parent){
        if(parent.$options.name === componentName) parents.push(parent)
        return parents.concat(findComponentUpward(parent, componentName))
    }
    return parents
}

// 向下找到最近的指定组件
function findComponentDownward(context, componentName){
    const childrens = context.$childrens;
    let children = null;

    if(childrens.length){
        for(const child in childrens){
            const name = child.$options.name;
            if(name === componentName){
                children = child
                break
            } else {
                children = findComponentDownward(context, componentName)
                if(children) break
            }
        }
    }
}

// 向下找到所有指定子组件
function findComponentsDownward(context, componentName){
    return context.$childrens.reduce((components, child) => {
        if(child.$options.name === componentName) components.push(child);
        const foundChilds = findComponentDownward(child, componentName);
        return components.concat(foundChilds);
    }, [])
}

// 找到所以的兄弟组件
function findBrothersComponents(context, componentName, exceptMe = true) {
    let res = context.$parent.$childrens.filter(item => {
        return item.$options.name === componentName
    })
    let index = res.findIndex(item => item._uid === context._uid);
    if(exceptMe){
        res.splice(index, 1)
    }
    return res;
}

function typeOf(obj){
    const toString = Object.prototype.toString;
    const map = {
        '[object Boolean]': 'boolean',
        '[object Number]': 'number',
        '[object String]': 'string',
        '[object Function]': 'function',
        '[object Array]': 'array',
        '[object Date]': 'date',
        '[object RegExp]': 'regExp',
        '[object Undefined]': 'undefined',
        '[object Null]': 'null',
        '[object Object]': 'object',
    };
    return map[toString.call(obj)]
}

function deepCopy(data){
    const t = typeOf(data);
    let o ;

    if(t === 'array'){
        o = []
    } 
    if(t === 'object'){
        o = {}
    } else {
        return data
    }

    if (t === 'array') {
        for (let i = 0; i < data.length; i++) {
            o.push(deepCopy(data[i]));
        }
    } else if (t === 'object') {
        for (let i in data) {
            o[i] = deepCopy(data[i]);
        }
    }
    return o;
}



export {
    findComponentUpward,
    findComponentsUpward,
    findComponentDownward,
    findComponentsDownward,
    findBrothersComponents,
    typeOf,
    deepCopy,
};